using System;
using System.Collections.Generic;
using System.Text;

namespace Noein.GeneticAlgorithm.Final
{
    public class GenoPheno
    {
        //maybe split the function and it's arguments for valid program generation
        private string data;
        private GenoPheno left;
        private GenoPheno right;
        public bool leaf;
        private int myType;

        /* ENUMS AND DATA TYPES */
        public enum dataType
        {
            function,
            argument
        }

        /* CONSTRUCTORS */
        public GenoPheno(string data, int myType, bool isLeaf)
        {
            //default values
            left = null;
            right = null;
            leaf = isLeaf;
            this.data = data;
            //for now, the user of this class will have to know what myType represents and 
            //how to use it exactly.  Abstracting this is for future streamlining
            this.myType = myType;
            //myType = (int)dataType.argument; //This will be useful later when we have more than two arguments

        }//GenoPheno


        //This may be a dangerous constructor to keep around.*********************
        /* public GenoPheno(GenoPheno left, GenoPheno right)
         {
             this.left = left;
             this.right = right;

             if (left == null && right == null)
             {
                 leaf = true;
             }//if

         }//GenoPheno
         */



        /* MUTATORS */
        public void setLeft(GenoPheno gp)
        {
            left = gp;

            if (left == null && right == null)
            {
                leaf = true;
            }
            else
            {
                leaf = false;
            }

        }//setLeft

        public void setRight(GenoPheno gp)
        {
            right = gp;

            if (left == null && right == null)
            {
                leaf = true;
            }
            else
            {
                leaf = false;
            }
        }//setRight



        /* ACCESSORS */
        public int getType()
        {
            return myType;
        }

        public GenoPheno getLeft()
        {
            return left;
        }//getLeft

        public GenoPheno getRight()
        {
            return right;
        }//getRight


        public string getLeftData()
        {
            if (left != null)
            {
                return left.getData();
            }
            else return null;
        }//getLeftData()

        public string getRightData()
        {
            if (right != null)
            {
                return right.getData();
            }
            else return null;
        }//getRightData()


        public string getData()
        {

            if (leaf)
                return data;
            else
                return "(" + data + " " + getLeftData() + " " + getRightData() + ")";
        }

        public int getDepth()
        {
            int l;
            int r;

            //get the children's depths if they exist
            if (getLeft() != null)
                l = left.getDepth();
            else
                l = 0;
            if (getRight() != null)
                r = right.getDepth();
            else
                r = 0;


            int d;

            if (l > r)
            {
                d = 1 + l;
            }
            else
            {
                d = 1 + r;
            }

            return d;

        }//getDepth


        public int getWidth()
        {

            int w;

            if (left == null && right == null)
            {
                w = 1;
            }
            else if (left == null && right != null)
            {
                w = right.getWidth();
            }
            else if (left != null && right == null)
            {
                w = left.getWidth();
            }
            else
            {
                int lw = left.getWidth();
                int rw = right.getWidth();
                if (lw > rw)
                {
                    w = lw;
                }
                else
                {
                    w = rw;
                }//else if

            }//else if

            return w;
        }//getWidth()

    }//GenoPheno
}//namespace Sandbox
